home *** CD-ROM | disk | FTP | other *** search
/ Mac Mania 4 / MacMania 4.toast / / Tools&Utilities / unshar-19 / CWMPWGlue.cp next >
Text File  |  1995-07-21  |  5KB  |  217 lines

  1. /*********************************************************************
  2. File        :    CWMPWGlue.cp -    Glue code for creating MPW tools with CodeWarrior
  3. Author    :    Matthias Neeracher <neeri@iis.ee.ethz.ch>
  4. Language    :    Metrowerks C++
  5.  
  6. $Log: CWMPWGlue.cp,v $
  7. *********************************************************************/
  8.  
  9. #include <Types.h>
  10. #include <FragLoad.h>
  11.  
  12. #include <unix.h>
  13. #include <errno.h>
  14. #include <stdlib.h>
  15.  
  16. #if !defined(powerc) && !defined(__powerc)
  17. #error "This file is neither needed nor working on an 68K"
  18. #endif
  19.  
  20. /*********************************************************************
  21.  * These procedure pointers will hold the glue routines to the MPW code
  22.  */
  23.  
  24. static int (*MPW_open)(const char * name, int flags);
  25. static int (*MPW_close)(int s);
  26. static int (*MPW_read)(int s, char *buffer, unsigned buflen);
  27. static int (*MPW_write)(int s, char *buffer, unsigned buflen);
  28. static long (*MPW_lseek)(int fd, long offset, int whence);
  29. static void (*MPW_exit)(int exitcode);
  30.  
  31. /* 
  32.  * Initialize glue if necessary. The test is done inline in InitStandardLib, 
  33.  * while the actual work is done in a separate procedure DoInitStandardLib.
  34.  */
  35. static Boolean beenThereDoneThat = false;
  36.     
  37. static void DoInitStandardLib()
  38. {
  39.     ConnectionID     StdCLib;
  40.     SymClass            symClass;
  41.     Ptr                 whoCares;
  42.     Str255            error;
  43.         
  44.     beenThereDoneThat = true;
  45.     
  46.     /* 
  47.      * We interface to the MPW standard library by dynamically connecting to the 
  48.      * code fragment. This technique has been suggested to me by Charlie Reiman.
  49.      */
  50.     if (GetSharedLibrary(
  51.             StringPtr("\pStdCLib"), kPowerPCArch, kLoadLib, &StdCLib, &whoCares, error)
  52.     )
  53.         return;
  54.     
  55.     if (FindSymbol(StdCLib, StringPtr("\popen"), (Ptr *) &MPW_open, &symClass))
  56.         goto failed_on_open;
  57.     if (FindSymbol(StdCLib, StringPtr("\pclose"), (Ptr *) &MPW_close, &symClass))
  58.         goto failed_on_close;
  59.     if (FindSymbol(StdCLib, StringPtr("\pread"), (Ptr *) &MPW_read, &symClass))
  60.         goto failed_on_read;
  61.     if (FindSymbol(StdCLib, StringPtr("\pwrite"), (Ptr *) &MPW_write, &symClass))
  62.         goto failed_on_write;
  63.     if (FindSymbol(StdCLib, StringPtr("\plseek"), (Ptr *) &MPW_lseek, &symClass))
  64.         goto failed_on_lseek;
  65.     if (FindSymbol(StdCLib, StringPtr("\pexit"), (Ptr *) &MPW_exit, &symClass))
  66.         goto failed_on_exit;
  67.     return;
  68.     
  69. failed_on_exit:
  70.     MPW_exit = nil;
  71. failed_on_lseek:
  72.     MPW_lseek = nil;
  73. failed_on_write:
  74.     MPW_write = nil;
  75. failed_on_read:
  76.     MPW_read = nil;
  77. failed_on_close:
  78.     MPW_close = nil;
  79. failed_on_open:
  80.     MPW_open = nil;
  81. }
  82.  
  83. inline void InitStandardLib()
  84. {
  85.     if (beenThereDoneThat)
  86.         return;
  87.     DoInitStandardLib();
  88. }
  89.  
  90. /* 
  91.  * Set errno if an error occurred. The Metrowerks library knows few error codes,
  92.  * so we simply return EDOM regardless of the actual error.
  93.  */
  94. inline int Error(int res)
  95. {
  96.     if (res == -1)
  97.         errno = EDOM;
  98.     
  99.     return res;
  100. }
  101.  
  102. inline long Error(long res)
  103. {
  104.     if (res == -1)
  105.         errno = EDOM;
  106.     
  107.     return res;
  108. }
  109.  
  110. #define MPW_O_RDONLY         0         /* Bits 0 and 1 are used internally */
  111. #define MPW_O_WRONLY         1         /* Values 0..2 are historical */
  112. #define MPW_O_RDWR          2        /* NOTE: it goes 0, 1, 2, *!* 8, 16, 32, ... */
  113. #define MPW_O_APPEND        (1<< 3)        /* append (writes guaranteed at the end) */
  114. #define MPW_O_RSRC         (1<< 4)        /* Open the resource fork */
  115. #define MPW_O_ALIAS        (1<< 5)        /* Open alias file */
  116. #define MPW_O_CREAT        (1<< 8)        /* Open with file create */
  117. #define MPW_O_TRUNC        (1<< 9)        /* Open with truncation */
  118. #define MPW_O_EXCL         (1<<10)     /* w/ O_CREAT:  Exclusive "create-only" */
  119. #define MPW_O_BINARY        (1<<11)     /* Open as a binary stream */
  120. #define MPW_O_NRESOLVE    (1<<14)        /* Don't resolve any aliases */
  121.  
  122. static int TranslateOpenFlags(int mode)
  123. {
  124.     int mpwMode;
  125.     
  126.     switch (mode & 3) {
  127.     case O_RDWR:
  128.         mpwMode = MPW_O_RDWR;
  129.         break;
  130.     case O_RDONLY:
  131.         mpwMode = MPW_O_RDONLY;
  132.         break;
  133.     case O_WRONLY:
  134.         mpwMode = MPW_O_WRONLY;
  135.         break;
  136.     }
  137.     if (mode & O_APPEND)
  138.         mpwMode |= MPW_O_APPEND;
  139.     if (mode & O_CREAT)
  140.         mpwMode |= MPW_O_CREAT;
  141.     if (mode & O_EXCL)
  142.         mpwMode |= MPW_O_EXCL;
  143.     if (mode & O_TRUNC)
  144.         mpwMode |= MPW_O_TRUNC;
  145.     if (mode & O_BINARY)
  146.         mpwMode |= MPW_O_BINARY;
  147.     
  148.     return mpwMode;
  149. }
  150.  
  151. /*
  152.  *    Opens a file and returns it's id.
  153.  */
  154. int open(const char *filename, int mode)
  155. {
  156.     InitStandardLib();
  157.     return Error(MPW_open ? MPW_open(filename, TranslateOpenFlags(mode)) : -1);
  158. }
  159.  
  160. /*
  161.  *    Reads from a file stream.
  162.  */
  163. int read(int fd, char *buf, int count)
  164. {
  165.     InitStandardLib();
  166.     return Error(MPW_read ? MPW_read(fd, buf, count) : -1);
  167. }
  168.  
  169. /*
  170.  *    Writes to a file stream.
  171.  */
  172. int write(int fd, const char *buf, int count)
  173. {
  174.     InitStandardLib();
  175.     return Error(MPW_write ? MPW_write(fd, (char *) buf, count) : -1);
  176. }
  177.  
  178. /*
  179.  *    Seek on a file stream.
  180.  */
  181. long lseek(int fd, long offset, int whence)
  182. {
  183.     /* whence constants for MPW and CodeWarrior are identical */
  184.     InitStandardLib();
  185.     return Error(MPW_lseek ? MPW_lseek(fd, offset, whence) : -1);
  186. }
  187.  
  188. /*
  189.  *    Closes an open file.
  190.  */
  191. int close(int fd)
  192. {
  193.     InitStandardLib();
  194.     return Error(MPW_close ? MPW_close(fd) : -1);
  195. }
  196.  
  197. /*
  198.  *    Closes an open file.
  199.  */
  200. void exit(int code)
  201. {
  202.     int i;
  203.     
  204.     for (i=0; i<FOPEN_MAX; i++)
  205.         if (_Files[i])
  206.             fclose(_Files[i]);
  207.     InitStandardLib();
  208.     if (MPW_exit)
  209.         MPW_exit(code);
  210. }
  211.  
  212. /* Stub for RemoveConsole */
  213.  
  214. extern "C" void RemoveConsole(void)
  215. {
  216. }
  217.